App.require(["canvasTool"], function (canvasTool) {
    function Gradient() {
        this.gradients = [];
        this.gradientMap = {};
        this.gradientObj = {};
    }

    Gradient.prototype = {
        Gradient: Gradient,
        dispose: function () {
            this.ctx = null;
        },
        destroy: function () {
            this.gradients.length = 0;
            this.gradients = null;
            this.gradientMap = null;
            this.gradientObj = null;
        },
        init: function (ctx) {
            this.ctx = ctx;
        },
        addGradient: function (obj) {
            if (!this.isHas(obj.id)) this.gradients.push(obj);
        },
        isHas: function (id) {
            var list = this.gradients;
            for (var i = 0; i < list.length; i++) {
                if (list[i].id === id) return list[i];
            }
            return false;
        },
        resetRadial: function (obj) {
            this.gradientMap["#" + obj.id] = null;
            var option = this.isHas(obj.id);
            if (!option) return;
            option.sx = obj.sx;
            option.sy = obj.sy;
            option.sr = obj.sr;
            option.fx = obj.fx;
            option.fy = obj.fy;
            option.fr = obj.fr;
            option.options = obj.options;
            this.gradientObj[obj.id] = null;
        },
        resetLinear: function (obj) {
            this.gradientMap["#" + obj.id] = null;
            var option = this.isHas(obj.id);
            if (!option) return;
            option.left = obj.left;
            option.top = obj.top;
            option.width = obj.top;
            option.height = obj.height;
            option.options = obj.options;
            this.gradientObj[obj.id] = null;
        },
        getUseById: function (id) {
            return this.gradientObj[id].slice();
        },
        createGradientByStr: function (str, target) {
            if (str.indexOf("#") == 0) {
                str = str.slice(1);
                var obj = this.isHas(str);
                if (!obj) return "black";
                var gradient = null;
                if (obj.type == "linear") gradient = this.ctx.createLinearGradient(obj.left, obj.top, obj.right, obj.bottom);
                else if (obj.type == "radial") gradient = this.ctx.createRadialGradient(obj.sx, obj.sy, obj.sr, obj.fx, obj.fy, obj.fr);

                for (var i = 0; i < obj.options.length; i++) {
                    var opt = obj.options[i];
                    gradient.addColorStop(parseFloat(opt.value), opt.color);
                }
                this.gradientMap["#" + str] = gradient;
                if (this.gradientObj[str]) {
                    if (this.gradientObj[str].indexOf(target) === -1) this.gradientObj[str].push(target);
                }
                else this.gradientObj[str] = [target];
                return gradient;
            }
        },
        remove: function (value, target) {
            var list = this.data.gradientObj[value];
            if (list) {
                var index = list.indexOf(target);
                if (index !== -1) list.splice(index, 1); 
            }
        },
    };

    App.define("gradient", {
        gradient: Gradient
    })
})